#-*- coding: UTF-8-*-

'''
更新10根解的算法
标准钢管6米/根,需要截断成不同长度的料,比如：
(1.2m, 0.8m*5, 2.3m, 4.1m, 0.65m*10, 3m*2, 1.8m, 1.9m*6, 1.5m, 5.1m*2, 3.1m*3)
如何获取最优计划：需要多少根标准钢管，每一根怎么截
'''

from http.server import HTTPServer, BaseHTTPRequestHandler
import json


data = {'result': 'this is a test'}
host = ('', 3333)


def GetBestPlan(mp_len, dict_plan):
    """
    分解相同规格的需求并排序
    {1.2: 1, 0.8: 5, 2.3: 1} => [1.2,0.8,0.8,0.8,0.8,0.8,2.3]
    """
    planLis = [y for y in dict_plan for x in range(0, dict_plan[y])]
    planLis.sort(reverse=True)

    res = []  # 计划表
    n = -1  # 当前分割序号
    while planLis :
        res.append([])
        n += 1
        Longest = planLis[0]  # 取当前最长的一根加入计划
        res[n].append(Longest)

        surplusBest = []  # 剩余长度的最优组合
        surplusLong = mp_len - Longest  # 剩余长度

        if surplusLong == 0:  # 剩余长度surplusLong为0，跳到下一根计划
            planLis.remove(Longest)
            continue

        # 过滤超过剩余长度的
        rightPrepare = list(filter(lambda x: x <= surplusLong, planLis[1:]))

        if not rightPrepare: # 无可以分割项，跳到下一根计划
            planLis.remove(Longest)
            continue

        left,right = 0,1 # 剩余长度组合标记
        currentComp = [] # 当前组合
        while left < len(rightPrepare) - 1:
            # 当前组合为空，添加左标记
            if not currentComp : currentComp.append(rightPrepare[left])
            t = surplusLong - sum(currentComp)
            if t == 0 : # 最佳计划,退出循环
                surplusBest = currentComp
                break
            t = surplusLong - sum(currentComp) - rightPrepare[right]
            if t < 0 :
                # 组合超出剩余长度
                # 对比最佳计划，如果更佳则替换
                # 左标记右移，又标记还原到到左标记+1
                if sum(currentComp) > sum(surplusBest) : surplusBest = currentComp
                left += 1
                right = left + 1
                currentComp = []
            else:
                currentComp.append(rightPrepare[right])
                if right == len(rightPrepare) - 1 :
                    # 如果右标记已经到末尾，对比最佳计划，如果更佳则替换
                    # 左标记右移1，右标记还原到左标记+1
                    if sum(currentComp) > sum(surplusBest): surplusBest = currentComp
                    left += 1
                    right = left + 1
                    currentComp = []
                else:
                    # 右标记右移1
                    right += 1

        # 添加到计划，并删除已添加项
        for x in surplusBest:
            res[n].append(x)
            planLis.remove(x)
        planLis.remove(Longest)
    return res


class Resquest(BaseHTTPRequestHandler):
    def do_POST(self):
        req_datas = self.rfile.read(int(self.headers['content-length']))
        res1 = req_datas.decode('utf-8')
        res = json.loads(res1)
        mp_len = res['mp_len']
        f_len = res['f_len']
        print(res['arr_len'])
        print(res['arr_size'])
        self.send_response(200)
        #self.send_header('Content-type', 'application/json')
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Access-Control-Allow-Headers', 'Origin, H5-User-Agent, Requested-Token, X-Requested-With, Content-Type, Accept, WG-App-Version, WG-Device-Id, WG-Network-Type, WG-Vendor, WG-OS-Type, WG-OS-Version, WG-Device-Model, WG-CPU, WG-Sid, WG-App-Id, WG-Token, XMLHttpRequest, access-control-allow-origin')
        self.send_header('Access-Control-Allow-Credentials', 'true')
        self.send_header('Access-Control-Allow-Methods', '*')
        self.end_headers()

        test = {}
        for inx, xqlen in enumerate(res['arr_len']):
            test[xqlen] = res['arr_size'][inx]

        #test = {1.2: 1, 0.8: 5, 2.3: 1, 4.1: 1, 0.65: 10, 3: 2, 1.8: 1, 1.9: 6, 1.5: 1, 5.1: 2, 3.1: 3}
        res = GetBestPlan(mp_len, test)
        ret = ''
        ret = "下料总数：%d" % len(res)
        ret += "\n"
        aflen = 0;
        allen = 0;
        for inx, item in enumerate(res):
            tmpylen = mp_len-sum(item)
            if tmpylen < f_len:
                aflen += tmpylen
            else:
                allen += tmpylen
            ret += "No:%2d 使用:%.2f 余:%.2f " % (inx + 1, sum(item), tmpylen)
            for iitem in item:
                ret += "%.2f" % iitem
                ret += " "
            ret += "\n"
        ret += "余料:%.2f 废料率:%.4f \n" % (allen, aflen/(len(res)*mp_len))
        self.wfile.write(ret.encode('utf-8'))


if __name__ == '__main__':
    server = HTTPServer(host, Resquest)
    print("Starting server, listen at: %s:%s" % host)
    server.serve_forever()
